/*
 * Copyright 2002-2016 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.springframework.beans.factory.config;

import org.springframework.beans.BeansException;
import org.springframework.lang.Nullable;

/**
 * Factory hook that allows for custom modification of new bean instances,
 * e.g. checking for marker interfaces or wrapping them with proxies.
 *
 * <p>ApplicationContexts can autodetect BeanPostProcessor beans in their
 * bean definitions and apply them to any beans subsequently created.
 * Plain bean factories allow for programmatic registration of post-processors,
 * applying to all beans created through this factory.
 *
 * <p>Typically, post-processors that populate beans via marker interfaces
 * or the like will implement {@link #postProcessBeforeInitialization},
 * while post-processors that wrap beans with proxies will normally
 * implement {@link #postProcessAfterInitialization}.
 *
 * @author Juergen Hoeller
 * @see InstantiationAwareBeanPostProcessor
 * @see DestructionAwareBeanPostProcessor
 * @see ConfigurableBeanFactory#addBeanPostProcessor
 * @see BeanFactoryPostProcessor
 * @since 10.10.2003
 */

/**
 * 允许自定义修改新 bean 实例的工厂钩子，例如检查标记接口或用代理包装它们。
 *
 * <p>ApplicationContexts 可以在它们的 bean 定义中自动检测 BeanPostProcessor bean，并将它们应用到随后创建的任何 bean。
 * 普通 bean 工厂允许以编程方式注册后处理器，适用于通过该工厂创建的所有 bean。
 *
 * <p>通常，通过标记接口等填充 bean 的后处理器将实现 {@link #postProcessBeforeInitialization}，
 * 而使用代理包装 bean 的后处理器通常将实现 {@link #postProcessAfterInitialization}。
 *
 * <p>
 *     todo
 *     这个接口执行在初始化 bean 的前后 , 一个在前 , 一个在后, aop的逻辑就是这个接口实现的
 *     详情请看实现类 {@link org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator}
 * </p>
 *
 * @Author yangSen
 * @date 2021-12-24 17:24
 * @see InstantiationAwareBeanPostProcessor
 * @see DestructionAwareBeanPostProcessor
 * @see ConfigurableBeanFactory#addBeanPostProcessor
 * @see BeanFactoryPostProcessor
 */
public interface BeanPostProcessor {

	/**
	 * Apply this BeanPostProcessor to the given new bean instance <i>before</i> any bean
	 * initialization callbacks (like InitializingBean's {@code afterPropertiesSet}
	 * or a custom init-method). The bean will already be populated with property values.
	 * The returned bean instance may be a wrapper around the original.
	 * <p>The default implementation returns the given {@code bean} as-is.
	 *
	 * @param bean     the new bean instance
	 * @param beanName the name of the bean
	 * @return the bean instance to use, either the original or a wrapped one;
	 * if {@code null}, no subsequent BeanPostProcessors will be invoked
	 * @throws org.springframework.beans.BeansException in case of errors
	 * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet
	 */
	/**
	 * 将此 BeanPostProcessor 应用于给定的新 bean 实例 <i>before<i> 任何 bean 初始化回调
	 * （如 InitializingBean 的 {@code afterPropertiesSet} 或自定义初始化方法）。
	 * bean 将已填充有属性值。返回的 bean 实例可能是原始实例的包装器。 <p>默认实现按原样返回给定的 {@code bean}。
	 * <p>
	 * 	   todo 之前执行的方法
	 * 	</p>
	 *
	 * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet
	 */
	@Nullable
	default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
		return bean;
	}

	/**
	 * Apply this BeanPostProcessor to the given new bean instance <i>after</i> any bean
	 * initialization callbacks (like InitializingBean's {@code afterPropertiesSet}
	 * or a custom init-method). The bean will already be populated with property values.
	 * The returned bean instance may be a wrapper around the original.
	 * <p>In case of a FactoryBean, this callback will be invoked for both the FactoryBean
	 * instance and the objects created by the FactoryBean (as of Spring 2.0). The
	 * post-processor can decide whether to apply to either the FactoryBean or created
	 * objects or both through corresponding {@code bean instanceof FactoryBean} checks.
	 * <p>This callback will also be invoked after a short-circuiting triggered by a
	 * {@link InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation} method,
	 * in contrast to all other BeanPostProcessor callbacks.
	 * <p>The default implementation returns the given {@code bean} as-is.
	 *
	 * @param bean     the new bean instance
	 * @param beanName the name of the bean
	 * @return the bean instance to use, either the original or a wrapped one;
	 * if {@code null}, no subsequent BeanPostProcessors will be invoked
	 * @throws org.springframework.beans.BeansException in case of errors
	 * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet
	 * @see org.springframework.beans.factory.FactoryBean
	 */
	/**
	 * 将此 BeanPostProcessor 应用于给定的新 bean 实例 <i>after<i> 任何 bean 初始化回调
	 * （如 InitializingBean 的 {@code afterPropertiesSet} 或自定义初始化方法）。
	 * bean 将已填充有属性值。返回的 bean 实例可能是原始实例的包装器。
	 *
	 * <p>在 FactoryBean 的情况下，将为 FactoryBean 实例和由 FactoryBean 创建的对象（从 Spring 2.0 开始）调用此回调。
	 * 后处理器可以通过相应的 {@code bean instanceof FactoryBean} 检查来决定是应用于 FactoryBean 或创建的对象还是两者。
	 *
	 * <p>与所有其他 BeanPostProcessor 回调相比，
	 * 此回调也将在由 {@link InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation} 方法触发的短路后调用。
	 *
	 * <p>默认实现按原样返回给定的 {@code bean}。
	 *
	 * <p>
	 *     todo
	 *     之后执行的方法
	 * </p>
	 *
	 * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet
	 * @see org.springframework.beans.factory.FactoryBean
	 */
	@Nullable
	default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
		return bean;
	}

}
